from django.shortcuts import render, get_object_or_404
from .models import Article, Recipe
from django.contrib.auth.models import User
from .forms import ProfileForm, ArticleCreateForm, ArticleUpdateForm, ContactForm, ArticleForm, BookFormSet
from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.urls import reverse, reverse_lazy
from django.views import generic
from django.utils import timezone
from django.views.decorators.cache import cache_page
from .forms import RecipeForm, IngredientFormSet
from django.shortcuts import redirect


# Create your views here.
@cache_page(60 * 15)  # 秒数， 缓存15分钟
def index(request):
    latest_articles = Article.objects.all().order_by('-pub_date')
    return render(request, 'blog/article_list.html', {'latest_articles': latest_articles})


# -----------------------------------------------------------------------------------------------


class IndexView(generic.ListView):
    # queryset = Article.objects.all().order_by('-pub_date')
    template_name = 'blog/article_list.html'
    context_object_name = 'latest_articles'

    # def get_context_date(self, **kwargs):
    #     context = super().get_context_data(**kwargs)
    #     context['now'] = timezone.now()
    #     return context

    def get_queryset(self):
        return Article.objects.filter(author=self.request.user).order_by('-pub_date')


# def article_detail(request, id):
#     article = get_object_or_404(Article, pk=id)
#     return render(request, 'blog/article_detail.html', {'article': article})
# --------------------------------------------------------------------------------------------------

class ArticleDetailView(generic.DeleteView):
    queryset = Article.objects.all().order_by('-pub_date')
    template_name = 'blog/article_detail.html'
    context_object_name = 'article'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['now'] = timezone.now()
        return context

    def get_object(self, queryset=None):
        obj = super().get_object(queryset=queryset)
        if obj.author != self.request.user:
            raise Http404()
        return obj


def profile_update(request, pk):
    user = get_object_or_404(User, pk=pk)

    if request.method == 'POST':
        form = ProfileForm(request.POST)

        if form.is_valid():
            user.first_name = form.cleaned_data['first_name']
            user.last_name = form.cleaned_data['last_name']
            user.save()

            return HttpResponse(reverse('users:profile', args=[user.id]))
    else:
        default_data = {'first_name': user.first_name, 'last_name': user.last_name, }
        form = ProfileForm(default_data)

    return render(request, 'user/profile_update.html', {'form': form, 'user': user})


class ArticleCreateView(generic.edit.CreateView):
    model = Article
    # fields = ['title', 'body', 'pub_date']
    template_name = 'blog/article_create_form.html'
    form_class = ArticleCreateForm

    def form_valid(self, form):
        form.author = self.request.user
        return super().form_invalid(form)


class ArticleUpdateView(generic.edit.UpdateView):
    model = Article
    # fields = ['title', 'body', 'pub_date']
    template_name = 'blog/article_update_form.html'
    form_class = ArticleUpdateForm

    def form_valid(self, form):
        form.do_sth()
        return super().form_valid(form)


class ContactView(generic.FormView):
    template_name = 'contact.html'
    form_class = ContactForm(
        initial={
            'name': 'First and last Name',
        },
    )
    success_url = '/thanks/'

    def form_valid(self, form):
        form.send_email()
        return super().form_valid(form)


class ArticleDeleteView(generic.edit.DeleteView):
    model = Article
    success_url = reverse_lazy('index')

    def get_queryset(self):
        return self.model.objects.filter(author=self.request.user)


def article_create(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/index/')
            # 过URL反向解析方法reverse先对命名URL(article_list)进行解析，然后再使用HttpResponseRedirect定向
            # HttpResponseRedirect(reverse('blog:article_list'))
            # 包含参数的URL
            # HttpResponseRedirect(reverse('blog:article_detail', args=[str(article.pk), article.slug]))
    else:
        form = ArticleForm()
    return render(request, 'blog/article_create_form.html', {'form': form})


def manager_books(request):
    if request.method == 'POST':
        formset = BookFormSet(request.POST, request.FILES)
        if formset.is_valid():
            pass
    else:
        formset = BookFormSet()
    return render(request, 'blog/manage_books.html', {'formset': formset})


def recipe_update(request, pk):
    recipe = get_object_or_404(Recipe, pk=pk)
    if request.method == 'POST':
        form = RecipeForm(request.POST, instance=recipe)

        if form.is_valid():
            recipe = form.save()
            ingredient_formset = IngredientFormSet(request.POST, instance=recipe)

            if ingredient_formset.is_valid():
                ingredient_formset.save()

        return redirect('/recipe/')
    else:
        form = RecipeForm(instance=recipe)
        ingredient_formset = IngredientFormSet(instance=recipe)
    return render(request, 'recipe/recipe_update.html', {'form': form,
                                                         'ingredient_formset': ingredient_formset})


def recipe_add(request):
    if request.method == 'POST':
        form = RecipeForm(request.POST)

        if form.is_valid():
            recipe = form.save()
            ingredient_formset = IngredientFormSet(request.POST, instance=recipe)

            if ingredient_formset.is_valid():
                ingredient_formset.save()

        return redirect('/recipe/')
    else:
        form = RecipeForm()
        ingredient_formset = IngredientFormSet()

    return render(request, 'recipe/recipe_add.html', {'form': form,
                                                      'ingredient_formset': ingredient_formset})


def request_test(request):
    # values = request.META.items()
    # html = []
    # for k, v in values:
    #     html.append('<tr><td>%s</td><td>%s</td></tr>/' % (k, v))
    # return HttpResponse('<table>%s</table>' % '\n'.join(html))
    user = request.user
    user_agent = request.META.get('HTTP_USER_AGENT', 'unknown')
    ip = request.META['REMOTE_ADDR']

    context = {'user': user, 'user_agent': user_agent, 'ip': ip}

    return render(request, 'blog/request_test.html', context)
